package com.example.blemulticondemo;

import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

import com.example.blemulticondemo.adapter.MessageAdapter;
import com.example.blemulticondemo.utils.BluetoothResponseUtil;
import com.example.blemulticondemo.utils.ByteToHexUtil;
import com.example.blemulticondemo.utils.Protocol;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";

    private static final int REQUEST_ENABLE_BT = 10;
    private static final int REQUEST_PERMISSIONS = 11;

    private RecyclerView rvMessages;
    private Button connectButton;
    private EditText messageInput;
    private Button sendButton;
    private LinearLayout llConnectedDevices;

    private BleManager bleManager;
    private BleListDialog bleListDialog;
    private MessageAdapter messageAdapter;

    private List<String> messageList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initBle();
        initAdapter();
    }

    private void initView() {
        rvMessages = findViewById(R.id.rvMessages);
        llConnectedDevices = findViewById(R.id.llConnectedDevices);
        connectButton = findViewById(R.id.connect_button);
        messageInput = findViewById(R.id.message_input);
        sendButton = findViewById(R.id.send_button);

        findViewById(R.id.btnScan).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startBluetoothScan();
            }
        });
        connectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDeviceListDialog();
            }
        });

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToTargetDevice();
            }
        });

        // 四个指令
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToTargetDeviceCMD(1);
            }
        });

        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToTargetDeviceCMD(2);
            }
        });

        findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToTargetDeviceCMD(3);
            }
        });

        findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToTargetDeviceCMD(4);
            }
        });

        findViewById(R.id.btnDelete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                messageList.clear();
                messageAdapter.notifyDataSetChanged();
            }
        });
    }

    private void initAdapter() {
        messageList = new ArrayList<>();
        rvMessages.setLayoutManager(new LinearLayoutManager(this));
        messageAdapter = new MessageAdapter(messageList);
        rvMessages.setAdapter(messageAdapter);
    }

    private void initBle() {
        // 判断是否支持蓝牙功能
        boolean bleFlag = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
        Log.e(TAG, "蓝牙支持方式 = " + bleFlag);
        if (!bleFlag) {
            Toast.makeText(getApplicationContext(), "设备不支持蓝牙功能", Toast.LENGTH_LONG).show();
            return;
        }

        bleManager = BleManager.getInstance(this);
        bleManager.setBleManagerCallback(new BleManager.BleManagerCallback() {
            @Override
            public void onDeviceFound(BluetoothDevice device) {
                Log.e(TAG, "Device found: " + device.getName() + " - " + device.getAddress());
                if (bleListDialog != null) {
                    bleListDialog.refreshDeviceList();
                }
            }

            @Override
            public void onScanFailed(int errorCode) {
                Log.e(TAG, "Scan failed with error code: " + errorCode);
            }

            @Override
            public void onDeviceConnected(BluetoothDevice device) {
                Log.e(TAG, "onDeviceConnected: " + device.getName() + " - " + device.getAddress());
                if (device != null) {
                    runOnUiThread(()->{
                        String message = device.getName() + " " + getCurTime() + ": 已连接";
                        addMessage(message);
                        refreshConnectedDevices();
                    });
                }
            }

            @Override
            public void onDeviceDisconnected(BluetoothDevice device) {
                Log.e(TAG, "onDeviceDisconnected: " + device.getName() + " - " + device.getAddress());
                if (device != null) {
                    runOnUiThread(()->{
                        String message = device.getName() + " " + getCurTime() + ": 断开连接";
                        addMessage(message);
                        refreshConnectedDevices();
                    });
                }
            }

            @Override
            public void onServicesDiscovered(BluetoothGatt gatt) {
                Log.e(TAG, "onServicesDiscovered: " + gatt.getDevice().getName());
            }

            @Override
            public void onDataReceived(BluetoothDevice device, byte[] data) {
                Log.e(TAG, "onDataReceived: " + device.getName() + " - " + device.getAddress());
                String result = ByteToHexUtil.byteToHexString(data, data.length);
                Log.e("接收到数据-->", result);
                runOnUiThread(()->{
                    String message = device.getName() + " " + getCurTime() + " 收到数据：" + result;
                    addMessage(message);
                    BluetoothResponseUtil.handleSerialData(MainActivity.this, device, result);
                });
            }
        });

        checkPermissionsAndStartScan();
    }

    // 权限验证并开始蓝牙扫描
    private void checkPermissionsAndStartScan() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                    checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.BLUETOOTH}, REQUEST_PERMISSIONS);
            } else {
                startBluetoothScan();
            }
        } else {
            startBluetoothScan();
        }
    }

    // 开始扫描
    private void startBluetoothScan() {
        if (!bleManager.isCloseBle()) {
            bleManager.startScan(10000); // 10 seconds
//            showDeviceListDialog();
        } else {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
    }


    // 给recycleView 添加消息列表
    private void addMessage(String message) {
        messageList.add(message);
        messageAdapter.notifyDataSetChanged();
        rvMessages.scrollToPosition(messageList.size() - 1);
    }

    // 刷新已连接的蓝牙设备
    private void refreshConnectedDevices() {
        llConnectedDevices.removeAllViews();
        for (BluetoothDevice device : bleManager.getConnectedDevices()) {
            CheckBox checkBox = new CheckBox(this);
            checkBox.setText(device.getName());
            checkBox.setTag(device);
            llConnectedDevices.addView(checkBox);
        }
    }

    private void sendMessageToTargetDevice() {
        String message = messageInput.getText().toString().trim();
        if (!TextUtils.isEmpty(message)) {
            for (int i = 0; i < llConnectedDevices.getChildCount(); i++) {
                View view = llConnectedDevices.getChildAt(i);
                if (view instanceof CheckBox && ((CheckBox)view).isChecked()) {
                    BluetoothDevice device = (BluetoothDevice) view.getTag();
                    bleManager.sendData(device, message.getBytes());

                    String logMessage = "给设备：" + device.getName() + " " + getCurTime() + " 发送内容：" + message;
                    addMessage(logMessage);
                }
            }
        }
    }

    // 发送特定指令
    private void sendMessageToTargetDeviceCMD(int cmdIndex) {
        String message = "";
            for (int i = 0; i < llConnectedDevices.getChildCount(); i++) {
                View view = llConnectedDevices.getChildAt(i);
                if (view instanceof CheckBox && ((CheckBox)view).isChecked()) {
                    BluetoothDevice device = (BluetoothDevice) view.getTag();
                    switch (cmdIndex) {
                        case 1:
                            message = "调用查询试剂卡状态指令";
                            Protocol.queryReagentStatus(view.getContext(), device);
                            break;
                        case 2:
                            message = "调用采集指令";
                            Protocol.getLightData(view.getContext(), device);
                            break;
                        case 3:
                            message = "调用获取设备信息指令";
                            Protocol.getFirmVersion(view.getContext(), device);
                            break;
                        case 4:
                            message = "调用获取SN码指令";
                            Protocol.readSN(view.getContext(), device);
                            break;
                    }
                    String logMessage = "\n给设备：" + device.getName() + " " + getCurTime() + " 发送内容：" + message;
                    addMessage(logMessage);
                }
            }
    }

    // 显示蓝牙列表对话框
    private void showDeviceListDialog() {
        if (bleListDialog == null) {
            bleListDialog = new BleListDialog(this);
        }
        if (!bleListDialog.isShowing()) {
            bleListDialog.show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_ENABLE_BT) {
            if (resultCode == RESULT_OK) {
//                Log.e(TAG, "=== 从这里开始执行 === ");
                startBluetoothScan();
            } else {
                Toast.makeText(getApplicationContext(), "拒绝开启蓝牙", Toast.LENGTH_LONG).show();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSIONS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startBluetoothScan();
            } else {
                Toast.makeText(this, "权限已被拒绝", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 获取当前时间
    private String getCurTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");//yyyy-MM-dd HH:mm:ss
        String d = "";
        try {
            d = sdf.format(new Date());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return d;
    }

}
